home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / TinyGL / ami / content / ad709 / tinygl / src / zbuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-15  |  9.7 KB  |  494 lines

  1. /*$T zbuffer.c GC 1.137 08/09/02 17:47:18 */
  2.  
  3. /* Z buffer: 16 bits Z / 16 bits color */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <assert.h>
  7. #include <string.h>
  8. #include "zbuffer.h"
  9.  
  10. /* Initilizaes the ZBuffer */
  11. ZBuffer *ZB_open(int xsize, int ysize, int mode, int nb_colors, unsigned char *color_indexes,
  12.                  int *color_table, void *frame_buffer) {
  13.     ZBuffer *zb;
  14.     int        size;
  15.     /*~~~~~~~~~*/
  16.  
  17.     zb = malloc(sizeof(ZBuffer));
  18.     if(zb == NULL) {
  19.         return NULL;
  20.     }
  21.  
  22.     zb->xsize = xsize;
  23.     zb->ysize = ysize;
  24.     zb->mode = mode;
  25.     zb->linesize = (xsize * PSZB + 3) &~3;
  26.  
  27.     switch(mode) {
  28. #ifdef TGL_FEATURE_8_BITS
  29.     case ZB_MODE_INDEX:
  30.         ZB_initDither(zb, nb_colors, color_indexes, color_table);
  31.         break;
  32. #endif
  33. #ifdef TGL_FEATURE_32_BITS
  34.     case ZB_MODE_RGBA:
  35. #endif
  36. #ifdef TGL_FEATURE_24_BITS
  37.     case ZB_MODE_RGB24:
  38. #endif
  39.     case ZB_MODE_5R6G5B:
  40.         zb->nb_colors = 0;
  41.         break;
  42.     default:
  43.         goto error;
  44.     }
  45.  
  46.     size = zb->xsize * zb->ysize * sizeof(unsigned short);
  47.  
  48.     zb->zbuf = malloc(size);
  49.     if(zb->zbuf == NULL) {
  50.         goto error;
  51.     }
  52.  
  53.     if(frame_buffer == NULL) {
  54.         zb->pbuf = malloc(zb->ysize * zb->linesize);
  55.         if(zb->pbuf == NULL) {
  56.             free(zb->zbuf);
  57.             goto error;
  58.         }
  59.  
  60.         zb->frame_buffer_allocated = 1;
  61.     }
  62.     else {
  63.         zb->frame_buffer_allocated = 0;
  64.         zb->pbuf = frame_buffer;
  65.     }
  66.  
  67.     zb->current_texture = NULL;
  68.  
  69.     return zb;
  70. error:
  71.     free(zb);
  72.     return NULL;
  73. }
  74.  
  75. /* */
  76. void ZB_close(ZBuffer *zb)
  77. {
  78. #ifdef TGL_FEATURE_8_BITS
  79.     if(zb->mode == ZB_MODE_INDEX) {
  80.         ZB_closeDither(zb);
  81.     }
  82. #endif
  83.     if(zb->frame_buffer_allocated) {
  84.         free(zb->pbuf);
  85.     }
  86.  
  87.     free(zb->zbuf);
  88.     free(zb);
  89. }
  90.  
  91. /* */
  92. void ZB_resize(ZBuffer *zb, void *frame_buffer, int xsize, int ysize) {
  93.     int size;
  94.  
  95.     /* xsize must be a multiple of 4 */
  96.     xsize = xsize &~3;
  97.  
  98.     zb->xsize = xsize;
  99.     zb->ysize = ysize;
  100.     zb->linesize = (xsize * PSZB + 3) &~3;
  101.  
  102.     size = zb->xsize * zb->ysize * sizeof(unsigned short);
  103.  
  104.     free(zb->zbuf);
  105.     zb->zbuf = malloc(size);
  106.  
  107.     if(zb->frame_buffer_allocated) {
  108.         free(zb->pbuf);
  109.     }
  110.  
  111.     if(frame_buffer == NULL) {
  112.         zb->pbuf = malloc(zb->ysize * zb->linesize);
  113.         zb->frame_buffer_allocated = 1;
  114.     }
  115.     else {
  116.         zb->pbuf = frame_buffer;
  117.         zb->frame_buffer_allocated = 0;
  118.     }
  119. }
  120.  
  121. /* */
  122. static void ZB_copyBuffer(ZBuffer *zb, void *buf, int linesize) {
  123.     unsigned char    *p1;
  124.     PIXEL            *q;
  125.     int                y, n;
  126.  
  127.     q = zb->pbuf;
  128.     p1 = buf;
  129.     n = zb->xsize * PSZB;
  130.     for(y = 0; y < zb->ysize; y++) {
  131.         memcpy(p1, q, n);
  132.         p1 += linesize;
  133.         q = (PIXEL *) ((char *) q + zb->linesize);
  134.     }
  135. }
  136.  
  137. #if TGL_FEATURE_RENDER_BITS == 16
  138.  
  139. /* 32 bpp copy */
  140.     #ifdef TGL_FEATURE_32_BITS
  141.         #define RGB16_TO_RGB32(p0, p1, v) { \
  142.         unsigned int    g, b, gb; \
  143.         g = (v & 0x07E007E0) << 5; \
  144.         b = (v & 0x001F001F) << 3; \
  145.         gb = g | b; \
  146.         p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8); \
  147.         p1 = (gb >> 16) | ((v & 0xF8000000) >> 8); \
  148.     }
  149.  
  150. /* */
  151.  
  152. static void ZB_copyFrameBufferRGB32(ZBuffer *zb, void *buf, int linesize) {
  153.     unsigned short    *q;
  154.     unsigned int    *p, *p1, v, w0, w1;
  155.     int                y, n;
  156.  
  157.     q = zb->pbuf;
  158.     p1 = (unsigned int *) buf;
  159.  
  160.     for(y = 0; y < zb->ysize; y++) {
  161.         p = p1;
  162.         n = zb->xsize >> 2;
  163.         do {
  164.             v = *(unsigned int *) q;
  165.         #if BYTE_ORDER == BIG_ENDIAN
  166.             RGB16_TO_RGB32(w1, w0, v);
  167.         #else
  168.             RGB16_TO_RGB32(w0, w1, v);
  169.         #endif
  170.             p[0] = w0;
  171.             p[1] = w1;
  172.  
  173.             v = *(unsigned int *) (q + 2);
  174.         #if BYTE_ORDER == BIG_ENDIAN
  175.             RGB16_TO_RGB32(w1, w0, v);
  176.         #else
  177.             RGB16_TO_RGB32(w0, w1, v);
  178.         #endif
  179.             p[2] = w0;
  180.             p[3] = w1;
  181.  
  182.             q += 4;
  183.             p += 4;
  184.         } while(--n > 0);
  185.  
  186.         p1 += linesize;
  187.     }
  188. }
  189.     #endif
  190.  
  191. /* 24 bit packed pixel handling */
  192.     #ifdef TGL_FEATURE_24_BITS
  193.  
  194. /*
  195.  * order: RGBR GBRG BRGB £
  196.  * XXX: packed pixel 24 bit support not tested £
  197.  * XXX: big endian case not optimised
  198.  */
  199.         #if BYTE_ORDER == BIG_ENDIAN
  200.             #define RGB16_TO_RGB24(p0, p1, p2, v1, v2) { \
  201.         unsigned int    r1, g1, b1, gb1, g2, b2, gb2; \
  202.         v1 = (v1 << 16) | (v1 >> 16); \
  203.         v2 = (v2 << 16) | (v2 >> 16); \
  204.         r1 = (v1 & 0xF800F800); \
  205.         g1 = (v1 & 0x07E007E0) << 5; \
  206.         b1 = (v1 & 0x001F001F) << 3; \
  207.         gb1 = g1 | b1; \
  208.         p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24); \
  209.         g2 = (v2 & 0x07E007E0) << 5; \
  210.         b2 = (v2 & 0x001F001F) << 3; \
  211.         gb2 = g2 | b2; \
  212.         p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff); \
  213.         p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16); \
  214.     }
  215.  
  216.         #else
  217.             #define RGB16_TO_RGB24(p0, p1, p2, v1, v2) { \
  218.         unsigned int    r1, g1, b1, gb1, g2, b2, gb2; \
  219.         r1 = (v1 & 0xF800F800); \
  220.         g1 = (v1 & 0x07E007E0) << 5; \
  221.         b1 = (v1 & 0x001F001F) << 3; \
  222.         gb1 = g1 | b1; \
  223.         p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24); \
  224.         g2 = (v2 & 0x07E007E0) << 5; \
  225.         b2 = (v2 & 0x001F001F) << 3; \
  226.         gb2 = g2 | b2; \
  227.         p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff); \
  228.         p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16); \
  229.     }
  230.         #endif
  231.  
  232. /* */
  233. static void ZB_copyFrameBufferRGB24(ZBuffer *zb, void *buf, int linesize) {
  234.     unsigned short    *q;
  235.     unsigned int    *p, *p1, w0, w1, w2, v0, v1;
  236.     int                y, n;
  237.  
  238.     q = zb->pbuf;
  239.     p1 = (unsigned int *) buf;
  240.     linesize = linesize * 3;
  241.  
  242.     for(y = 0; y < zb->ysize; y++) {
  243.         p = p1;
  244.         n = zb->xsize >> 2;
  245.         do {
  246.             v0 = *(unsigned int *) q;
  247.             v1 = *(unsigned int *) (q + 2);
  248.             RGB16_TO_RGB24(w0, w1, w2, v0, v1);
  249.             p[0] = w0;
  250.             p[1] = w1;
  251.             p[2] = w2;
  252.  
  253.             q += 4;
  254.             p += 3;
  255.         } while(--n > 0);
  256.         (char *) p1 += linesize;
  257.     }
  258. }
  259.     #endif
  260.  
  261. /* */
  262. void ZB_copyFrameBuffer(ZBuffer *zb, void *buf, int linesize) {
  263.     switch(zb->mode) {
  264.     #ifdef TGL_FEATURE_8_BITS
  265.     case ZB_MODE_INDEX:
  266.         ZB_ditherFrameBuffer(zb, buf, linesize >> 1);
  267.         break;
  268.     #endif
  269.     #ifdef TGL_FEATURE_16_BITS
  270.     case ZB_MODE_5R6G5B:
  271.         ZB_copyBuffer(zb, buf, linesize);
  272.         break;
  273.     #endif
  274.     #ifdef TGL_FEATURE_32_BITS
  275.     case ZB_MODE_RGBA:
  276.         ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1);
  277.         break;
  278.     #endif
  279.     #ifdef TGL_FEATURE_24_BITS
  280.     case ZB_MODE_RGB24:
  281.         ZB_copyFrameBufferRGB24(zb, buf, linesize >> 1);
  282.         break;
  283.     #endif
  284.     default:
  285.         assert(0);
  286.     }
  287. }
  288. #endif /* TGL_FEATURE_RENDER_BITS == 16 */
  289.  
  290. #if TGL_FEATURE_RENDER_BITS == 24
  291.     #define RGB24_TO_RGB16(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
  292.  
  293. /* XXX: not optimized */
  294. static void ZB_copyFrameBuffer5R6G5B(ZBuffer *zb, void *buf, int linesize) {
  295.     PIXEL            *q;
  296.     unsigned short    *p, *p1;
  297.     int                y, n;
  298.  
  299.     q = zb->pbuf;
  300.     p1 = (unsigned short *) buf;
  301.  
  302.     for(y = 0; y < zb->ysize; y++) {
  303.         p = p1;
  304.         n = zb->xsize >> 2;
  305.         do {
  306.             p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]);
  307.             p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]);
  308.             p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]);
  309.             p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]);
  310.             q = (PIXEL *) ((char *) q + 4 * PSZB);
  311.             p += 4;
  312.         } while(--n > 0);
  313.         p1 = (unsigned short *) ((char *) p1 + linesize);
  314.     }
  315. }
  316.  
  317. /* */
  318. void ZB_copyFrameBuffer(ZBuffer *zb, void *buf, int linesize) {
  319.     switch(zb->mode) {
  320.     #ifdef TGL_FEATURE_16_BITS
  321.     case ZB_MODE_5R6G5B:
  322.         ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
  323.         break;
  324.     #endif
  325.     #ifdef TGL_FEATURE_24_BITS
  326.     case ZB_MODE_RGB24:
  327.         ZB_copyBuffer(zb, buf, linesize);
  328.         break;
  329.     #endif
  330.     default:
  331.         assert(0);
  332.     }
  333. }
  334. #endif /* TGL_FEATURE_RENDER_BITS == 24 */
  335.  
  336. #if TGL_FEATURE_RENDER_BITS == 32
  337.     #define RGB32_TO_RGB16(v)    (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
  338.  
  339. /* XXX: not optimized */
  340. static void ZB_copyFrameBuffer5R6G5B(ZBuffer *zb, void *buf, int linesize) {
  341.     PIXEL            *q;
  342.     unsigned short    *p, *p1;
  343.     int                y, n;
  344.  
  345.     q = zb->pbuf;
  346.     p1 = (unsigned short *) buf;
  347.  
  348.     for(y = 0; y < zb->ysize; y++) {
  349.         p = p1;
  350.         n = zb->xsize >> 2;
  351.         do {
  352.             p[0] = RGB32_TO_RGB16(q[0]);
  353.             p[1] = RGB32_TO_RGB16(q[1]);
  354.             p[2] = RGB32_TO_RGB16(q[2]);
  355.             p[3] = RGB32_TO_RGB16(q[3]);
  356.             q += 4;
  357.             p += 4;
  358.         } while(--n > 0);
  359.         p1 = (unsigned short *) ((char *) p1 + linesize);
  360.     }
  361. }
  362.  
  363. /* */
  364. void ZB_copyFrameBuffer(ZBuffer *zb, void *buf, int linesize) {
  365.     switch(zb->mode) {
  366.     #ifdef TGL_FEATURE_16_BITS
  367.     case ZB_MODE_5R6G5B:
  368.         ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
  369.         break;
  370.     #endif
  371.     #ifdef TGL_FEATURE_32_BITS
  372.     case ZB_MODE_RGBA:
  373.         ZB_copyBuffer(zb, buf, linesize);
  374.         break;
  375.     #endif
  376.     default:
  377.         assert(0);
  378.     }
  379. }
  380. #endif \
  381.  \
  382.     /*
  383.      * TGL_FEATURE_RENDER_BITS == 32 £
  384.      * adr must be aligned on an 'int'
  385.      */
  386. void memset_s(void *adr, int val, int count) {
  387.     int                i, n, v;
  388.     unsigned int    *p;
  389.     unsigned short    *q;
  390.  
  391.     p = adr;
  392.     v = val | (val << 16);
  393.  
  394.     n = count >> 3;
  395.     for(i = 0; i < n; i++) {
  396.         p[0] = v;
  397.         p[1] = v;
  398.         p[2] = v;
  399.         p[3] = v;
  400.         p += 4;
  401.     }
  402.  
  403.     q = (unsigned short *) p;
  404.     n = count & 7;
  405.     for(i = 0; i < n; i++) {
  406.         *q++ = val;
  407.     }
  408. }
  409.  
  410. /* */
  411. void memset_l(void *adr, int val, int count) {
  412.     int                i, n, v;
  413.     unsigned int    *p;
  414.  
  415.     p = adr;
  416.     v = val;
  417.     n = count >> 2;
  418.     for(i = 0; i < n; i++) {
  419.         p[0] = v;
  420.         p[1] = v;
  421.         p[2] = v;
  422.         p[3] = v;
  423.         p += 4;
  424.     }
  425.  
  426.     n = count & 3;
  427.     for(i = 0; i < n; i++) {
  428.         *p++ = val;
  429.     }
  430. }
  431.  
  432. /* count must be a multiple of 4 and >= 4 */
  433. void memset_RGB24(void *adr, int r, int v, int b, long count) {
  434.     long            i, n;
  435.     register long    v1, v2, v3, *pt = (long *) (adr);
  436.     unsigned char    *p, R = (unsigned char) r, V = (unsigned char) v, B = (unsigned char) b;
  437.  
  438.     p = (unsigned char *) adr;
  439.     *p++ = R;
  440.     *p++ = V;
  441.     *p++ = B;
  442.     *p++ = R;
  443.     *p++ = V;
  444.     *p++ = B;
  445.     *p++ = R;
  446.     *p++ = V;
  447.     *p++ = B;
  448.     *p++ = R;
  449.     *p++ = V;
  450.     *p++ = B;
  451.     v1 = *pt++;
  452.     v2 = *pt++;
  453.     v3 = *pt++;
  454.     n = count >> 2;
  455.     for(i = 1; i < n; i++) {
  456.         *pt++ = v1;
  457.         *pt++ = v2;
  458.         *pt++ = v3;
  459.     }
  460. }
  461.  
  462. /* */
  463. void ZB_clear(ZBuffer *zb, int clear_z, int z, int clear_color, int r, int g, int b)
  464. {
  465. #if TGL_FEATURE_RENDER_BITS != 24
  466.     int        color;
  467. #endif
  468.     int        y;
  469.     PIXEL    *pp;
  470.  
  471.     if(clear_z) {
  472.         memset_s(zb->zbuf, z, zb->xsize * zb->ysize);
  473.     }
  474.  
  475.     if(clear_color) {
  476.         pp = zb->pbuf;
  477.         for(y = 0; y < zb->ysize; y++)
  478.         {
  479. #if TGL_FEATURE_RENDER_BITS == 15 || TGL_FEATURE_RENDER_BITS == 16
  480.             color = RGB_TO_PIXEL(r, g, b);
  481.             memset_s(pp, color, zb->xsize);
  482. #elif TGL_FEATURE_RENDER_BITS == 32
  483.             color = RGB_TO_PIXEL(r, g, b);
  484.             memset_l(pp, color, zb->xsize);
  485. #elif TGL_FEATURE_RENDER_BITS == 24
  486.             memset_RGB24(pp, r >> 8, g >> 8, b >> 8, zb->xsize);
  487. #else
  488.     #error TODO
  489. #endif
  490.             pp = (PIXEL *) ((char *) pp + zb->linesize);
  491.         }
  492.     }
  493. }
  494.